package com.lefevre.cms.web.action.upgrade;

import com.lefevre.cms.bean.upgrade.UpgradeLog;
import com.lefevre.cms.bean.upgrade.UpgradeSystem;
import com.lefevre.cms.service.upgrade.UpgradeService;
import com.lefevre.cms.utils.FileUtil;
import com.lefevre.cms.utils.JsonUtils;
import com.lefevre.cms.utils.PathUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 升级管理
 */
@Component("upgradeManage")
public class UpgradeManage {
    private static final Logger logger = LoggerFactory.getLogger(UpgradeManage.class);

    @Resource
    UpgradeService upgradeService;

    /**
     * 处理数据
     *
     * @param upgradeId 升级Id
     */
    @Async
    public void manipulationData(String upgradeId) {
        UpgradeSystem upgradeSystem = upgradeService.findUpgradeSystemById(upgradeId);
        //执行升级数据处理
        if (upgradeSystem.getRunningStatus() >= 40) {
            String oldVersion = upgradeSystem.getOldSystemVersion().replaceAll("\\.", "_");//点替换为下划线
            String newVersion = upgradeSystem.getId().replaceAll("\\.", "_");//点替换为下划线
            boolean error = false;
            //反射调用升级数据处理类
            try {
                Class<?> cls = Class.forName("com.lefevre.cms.web.action.upgrade.impl.Upgrade" + oldVersion.trim() + "to" + newVersion.trim());
                Method m = cls.getDeclaredMethod("run", String.class);
                m.invoke(cls, upgradeId);
            } catch (Exception e) {
                error = true;
                logger.error("升级处理数据错误", e);
            } finally {
                if (error) {
                    upgradeService.addLog(upgradeId, JsonUtils.toJSONString(new UpgradeLog(new Date(), "调用升级数据处理类出错", 2)) + ",");
                }
            }
        }
    }

    /**
     * 查询下级目录列表
     *
     * @param path 路径 WEB-INF/data/upgrade
     */
    public List<String> querySubdirectoryList(String path) {
        Set<String> folderList = new LinkedHashSet<>();
        try {
            org.springframework.core.io.Resource[] resources = new PathMatchingResourcePatternResolver().
                    getResources(ResourceUtils.CLASSPATH_URL_PREFIX + path + "/**");
            String formatRootPath = FileUtil.toLeftSlant(PathUtil.rootPath());
            // 遍历文件内容
            for (org.springframework.core.io.Resource resource : resources) {

                if ("jar".equals(resource.getURL().getProtocol())) {//jar:开头
                    //jar:file:/D:/test2/test.jar!/BOOT-INF/classes!/WEB-INF/data/upgrade/5.1to5.2/cms/
                    if (resource.getURL().getPath().endsWith("/")) { //如果是文件夹
                        //源相对路径
                        String sourceRelativePath = StringUtils.substringAfter(StringUtils.substringAfterLast(resource.getURL().getPath(), "!/"), path + "/");// 5.1to5.2/cms/
                        //目标路径
                        String distPath = StringUtils.substringBefore(sourceRelativePath, "/");//截取到等于第二个参数的字符串为止
                        if (distPath != null && !"".equals(distPath.trim())) {
                            folderList.add(distPath);
                        }
                    }
                } else {//file:开头
                    //file:/F:/JAVA/cms-pro/target/classes/WEB-INF/data/upgrade/5.1to5.2/cms/
                    if (resource.getURL().getPath().endsWith("/")) { //如果是文件夹
                        String sourceRelativePath = StringUtils.substringAfter(resource.getURL().getPath(), formatRootPath + "/" + path + "/");//5.1to5.2/cms/
                        //目标路径
                        String distPath = StringUtils.substringBefore(sourceRelativePath, "/");//截取到等于第二个参数的字符串为止
                        if (distPath != null && !"".equals(distPath.trim())) {
                            folderList.add(distPath);
                        }
                    }
                }
            }
        } catch (IOException e) {
            logger.error("查询下级目录列表异常 " + path, e);
        }
        return new ArrayList<>(folderList);
    }


    /**
     * 查询/添加任务运行标记
     *
     * @param count 次数  -1为查询方式
     * @return
     */
    @Cacheable(value = "upgradeManage_cache_taskRunMark", key = "'taskRunMark'")
    public Long taskRunMark_add(Long count) {
        return count;
    }

    /**
     * 删除任务运行标记
     *
     * @return
     */
    @CacheEvict(value = "upgradeManage_cache_taskRunMark", key = "'taskRunMark'")
    public void taskRunMark_delete() {
    }

}
